home *** CD-ROM | disk | FTP | other *** search
- // copying
- // Copyright (C) 1991 David Stoutamire (daves@alpha.ces.cwru.edu)
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, version 2.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program (file "COPYING"); if not, write to the Free
- // Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- #include "iku.h"
-
- // class PatRep
- PatRep* PatRep::duplicate() {
- fatal("got call to PatRep::duplicate().");
- }
- patenum PatRep::identification() {
- fatal("got call to PatRep::identification.");
- }
- void PatRep::extract(PatternusingOpponent& op, Board& b, Move m) {
- fatal("got call to PatRep::extract.");
- }
- bool PatRep::operator== (PatRep& vs) {
- fatal("got call to PatRep::operator== (PatRep& vs).");
- }
- unsigned int PatRep::hash() {
- fatal("got call to PatRep::hash().");
- }
- String PatRep::str() {
- fatal("got call to PatRep::str().");
- }
-
- // class Pattern
- Pattern::Pattern(patenum patterntouse=patnxn, String s="") {
- switch(patterntouse) {
- case patnxn:
- rep=new Patnxn(s);
- break;
- case patgroup:
- rep=new Patgroup(s);
- break;
- case patdiamond:
- rep=new Patdiamond(s);
- break;
- default:
- fatal("Error in Pattern::Pattern().");
- }
- }
- Pattern::Pattern(Pattern& p) {
- rep=p.rep->duplicate();
- }
- Pattern::~Pattern() {
- delete rep;
- }
- void Pattern::extract(PatternusingOpponent& op,
- Board& b, Move m) {
- return(rep->extract(op,b,m));
- }
- bool Pattern::operator== (Pattern& vs) {
- return((*rep)==(*(vs.rep)));
- }
- void Pattern::operator= (Pattern& p) {
- delete rep;
- rep=p.rep->duplicate();
- }
- unsigned int Pattern::hash(int hashsize=0) {
- // return between 0...hashsize-1
- int h=rep->hash();
- if (hashsize!=0)
- return((h>?(-h))%hashsize);
- else
- return h;
- }
- String Pattern::str() {
- return(rep->str());
- }
-
- // class Patnxn
- // Patnxn is a simple square pattern centered around move in question.
- PatRep* Patnxn::duplicate() {
- Patnxn *p=new Patnxn;
-
- p->rep=rep;
- return(p);
- }
- Patnxn::Patnxn(String s="") {
- rep=s;
- }
- String Patnxn::str() {
- return(rep);
- }
- patenum Patnxn::identification() {
- return(patnxn);
- }
- void Patnxn::extract(PatternusingOpponent& op,
- Board& b, Move m) {
- if (m.kind!=play)
- fatal("Asked to extract a play or resignation: "+m.str());
-
- int i,j;
- rep="";
- for (int sym=0;sym<8;sym++) {
- char buf[(op.nxnsize*2+1)*(op.nxnsize*2+1)];
- int at=0;
- for (i=(-op.nxnsize);i<=op.nxnsize;i++)
- for (j=(-op.nxnsize);j<=op.nxnsize;j++) {
- if (i==0&&j==0)
- continue;
- Pos p(m.where.row+syma(i,j,sym),m.where.col+symb(i,j,sym));
- if (!p.valid())
- buf[at++]='c';
- else switch(b.board[p.row][p.col]) {
- case black:
- if (b.turntoplay==blackstone)
- buf[at++]='u';
- else
- buf[at++]='t';
- break;
- case white:
- if (b.turntoplay==whitestone)
- buf[at++]='u';
- else
- buf[at++]='t';
- break;
- case empty:
- buf[at++]='e';
- break;
- default:
- fatal("Odd switch in genericextract.");
- }
- }
- buf[at]='\0';
- if (String(buf)>rep)
- rep=buf;
- }
- }
- bool Patnxn::operator== (PatRep& vs) {
- if (vs.identification()!=patnxn)
- fatal("type mismatch in patnxn operator==.");
- return(rep==((Patnxn*)(&vs))->rep);
- }
- unsigned int Patnxn::hash() {
- return(hashpjw((char*) rep));
- }
-
- // class Patdiamond
- // simple diamond pattern.
- PatRep* Patdiamond::duplicate() {
- Patdiamond *p=new Patdiamond;
-
- p->rep=rep;
- return(p);
- }
- Patdiamond::Patdiamond(String s="") {
- rep=s;
- }
- String Patdiamond::str() {
- return(rep);
- }
- patenum Patdiamond::identification() {
- return(patdiamond);
- }
- void Patdiamond::extract(PatternusingOpponent& op,
- Board& b, Move m) {
- if (m.kind!=play)
- fatal("Asked to extract non-play in Patdiamond: "+m.str());
-
- int i=0,j=0; // initialized just to shut up g++
- rep="";
- for (int sym=0;sym<8;sym++) {
- int seen=0;
- char buf[999];
- int at=0;
- int currad,side,k;
- for (currad=1;currad<=op.mindiamondsize||
- (currad<=op.maxdiamondsize&&seen<op.diamondmustsee);currad++)
- for (side=0;side<4;side++)
- for (k=0;k<currad;k++) {
- switch (side) {
- case 0: i=k; j=currad-k; break;
- case 1: i=currad-k; j= -k; break;
- case 2: i= -k; j=k-currad; break;
- case 3: i=k-currad; j=k; break;
- }
- Pos p(m.where.row+syma(i,j,sym),m.where.col+symb(i,j,sym));
- if (!p.valid()) {
- buf[at++]='c';
- }
- else switch(b.board[p.row][p.col]) {
- case black:
- if (b.turntoplay==blackstone)
- buf[at++]='u';
- else
- buf[at++]='t';
- if (op.libscutoff!=0)
- buf[at++]='0'+(b.libsat(p)<?op.libscutoff);
- seen++;
- break;
- case white:
- if (b.turntoplay==whitestone)
- buf[at++]='u';
- else
- buf[at++]='t';
- if (op.libscutoff!=0)
- buf[at++]='0'+(b.libsat(p)<?op.libscutoff);
- seen++;
- break;
- case empty:
- buf[at++]='e';
- break;
- default:
- fatal("Odd switch in genericextract.");
- }
- }
- buf[at]='\0';
- if (String(buf)>rep)
- rep=buf;
- }
- }
- bool Patdiamond::operator== (PatRep& vs) {
- if (vs.identification()!=patdiamond)
- fatal("type mismatch in patdiamond operator==.");
- return(rep==((Patdiamond*)(&vs))->rep);
- }
- unsigned int Patdiamond::hash() {
- return(hashpjw((char*) rep));
- }
-
- // class Patgroup
- // graph-based pattern extraction. Very ugly code, sorry.
- // globals used by class Patgroup
- boardenum tbp[19][19];
- const int maxgroups=361;
- int seencounter;
- bool weareblack;
- char adj[maxgroups][maxgroups];
- int adjcount[maxgroups];
- int grp[19][19], grpcount;
- boardenum grpcolor[maxgroups];
- int grpseen[maxgroups];
- int grpqueue[maxgroups];
- int newqueue[maxgroups];
- int numingrpq, numinnewq;
- Board *Patgroup_bd;
- PatRep* Patgroup::duplicate() {
- Patgroup *p=new Patgroup;
-
- p->rep=rep;
- return(p);
- }
- Patgroup::Patgroup(String s="") {
- rep=s;
- }
- String Patgroup::str() {
- return(rep);
- }
- patenum Patgroup::identification() {
- return(patgroup);
- }
- void Patgroup::extract(PatternusingOpponent& op,
- Board& b, Move m) {
- int i,j;
-
- if (m.kind!=play)
- fatal("in Patgroup:: asked to extract something non-play: "+m.str());
-
- bool changed=false;
- doboard(i,j) {
- if (changed)
- break;
- if (b.board[i][j]!=tbp[i][j])
- changed=true;
- }
- if (changed) {
- doboard(i,j)
- tbp[i][j]=b.board[i][j];
- Patgroup_groupify();
- }
- weareblack=(b.turntoplay==black);
- for (i=0;i<grpcount;i++)
- grpseen[i]= -1;
- numinnewq=1;
- newqueue[0]=grp[m.where.row][m.where.col];
- grpseen[newqueue[0]]=0;
- seencounter=1;
- rep="";
- for (i=op.groupradius;i>0;i--)
- rep+=Patgroup_gex(i);
- }
- bool Patgroup::operator== (PatRep& vs) {
- if (vs.identification()!=patgroup)
- fatal("type mismatch in patgroup operator==.");
- return(rep==((Patgroup*)(&vs))->rep);
- }
- unsigned int Patgroup::hash() {
- return(hashpjw((char*) rep));
- }
- void Patgroup_flood(int r, int c, int val, boardenum color) {
- if (r<0||c<0||r>18||c>18||grp[r][c]!= -1||tbp[r][c]!=color)
- return;
- grp[r][c]=val;
- if (color!=empty) {
- Patgroup_flood(r-1,c,val,color);
- Patgroup_flood(r+1,c,val,color);
- Patgroup_flood(r,c-1,val,color);
- Patgroup_flood(r,c+1,val,color);
- }
- }
- void Patgroup_groupify() {
- int i,j;
- doboard(i,j)
- grp[i][j]= -1;
- grpcount=0;
- doboard(i,j)
- if (grp[i][j]== -1) {
- grpcolor[grpcount]=tbp[i][j];
- Patgroup_flood(i,j,grpcount++,tbp[i][j]);
- }
- for (i=0;i<grpcount;i++)
- for (j=0;j<grpcount;j++)
- adj[i][j]=0;
- doboard(i,j) {
- int g=grp[i][j];
- if (i>0) {
- adj[g][grp[i-1][j]]=1;
- adj[grp[i-1][j]][g]=1;
- }
- if (j>0) {
- adj[g][grp[i][j-1]]=1;
- adj[grp[i][j-1]][g]=1;
- }
- if (i<18) {
- adj[g][grp[i+1][j]]=1;
- adj[grp[i+1][j]][g]=1;
- }
- if (j<18) {
- adj[g][grp[i][j+1]]=1;
- adj[grp[i][j+1]][g]=1;
- }
- }
- for (i=0;i<grpcount;i++) {
- adj[i][i]=0;
- adjcount[i]=0;
- for (j=0;j<grpcount;j++)
- adjcount[i]+=adj[i][j];
- }
- }
- String Patgroup_gex(int iter) {
- int i,j;
- String s;
-
- numingrpq=0;
- for (i=0;i<numinnewq;i++) {
- for (j=0;j<grpcount;j++)
- if (adj[newqueue[i]][j])
- if (grpseen[j]>=0)
- s+=form("#%d",grpseen[j]);
- for (j=0;j<grpcount;j++)
- if (adj[newqueue[i]][j])
- if (grpseen[j]== -1&&grpcolor[j]==empty) {
- if (iter==1)
- s+="e";
- else
- s+=form("e%d",adjcount[j]);
- grpqueue[numingrpq++]=j;
- grpseen[j]=seencounter++;
- }
- for (j=0;j<grpcount;j++)
- if (adj[newqueue[i]][j])
- if (grpseen[j]== -1)
- if ((weareblack&&grpcolor[j]==black)
- ||((!weareblack)&&grpcolor[j]==white)) {
- if (iter==1)
- s+="u";
- else
- s+=form("u%d",adjcount[j]);
- grpqueue[numingrpq++]=j;
- grpseen[j]=seencounter++;
- }
- for (j=0;j<grpcount;j++)
- if (adj[newqueue[i]][j])
- if (grpseen[j]== -1)
- if ((weareblack&&grpcolor[j]==white)
- ||((!weareblack)&&grpcolor[j]==black)) {
- if (iter==1)
- s+="t";
- else
- s+=form("t%d",adjcount[j]);
- grpqueue[numingrpq++]=j;
- grpseen[j]=seencounter++;
- }
- }
- numinnewq=numingrpq;
- for (i=0;i<numinnewq;i++)
- newqueue[i]=grpqueue[i];
- return(s+".");
- }
-